home *** CD-ROM | disk | FTP | other *** search
-
- /* Zug.c : individuelle Zugbewertung */
-
- #include "Adt.h"
-
- Feld * Bauer();
- Feld * Springer();
- Feld * RestFig();
- struct Knoten * GibKnoten();
-
- long ZugBaumI();
- long ZugBaumII();
-
- int Figurwert[] = { 0, 100, 300, 300, 500, 900, 21000 };
- int Stelwert[][ 8 ][ 8 ] = {
- { /* wbauer: */
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 35, 70, 55, 75, 75, 55, 70, 35 },
- { 30, 65, 50, 70, 70, 50, 65, 30 },
- { 25, 60, 45, 65, 65, 45, 60, 25 },
- { 20, 55, 40, 62, 62, 40, 55, 20 },
- { 10, 50, 30, 40, 40, 30, 50, 10 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { /* sbauer: */
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 10, 50, 30, 40, 40, 30, 50, 10 },
- { 20, 55, 40, 62, 62, 40, 55, 20 },
- { 25, 60, 45, 65, 65, 45, 60, 25 },
- { 30, 65, 50, 70, 70, 50, 65, 30 },
- { 35, 70, 55, 75, 75, 55, 70, 35 },
- { 0, 0, 0, 0, 0, 0, 0, 0 } },
- { /* springer: */
- { 0, 12, 24, 24, 24, 24, 12, 0 },
- { 12, 24, 48, 48, 48, 48, 24, 12 },
- { 24, 48, 72, 72, 72, 72, 48, 24 },
- { 24, 48, 72, 72, 72, 72, 48, 24 },
- { 24, 48, 72, 72, 72, 72, 48, 24 },
- { 24, 48, 72, 72, 72, 72, 48, 24 },
- { 12, 24, 48, 48, 48, 48, 24, 12 },
- { 0, 12, 24, 24, 24, 24, 12, 0 } },
- { /* laeufer: */
- { 7, 7, 0, 0, 0, 0, 7, 7 },
- { 7, 21, 21, 14, 14, 21, 21, 7 },
- { 21, 21, 35, 35, 35, 35, 21, 21 },
- { 35, 14, 35, 35, 35, 35, 14, 35 },
- { 35, 14, 35, 35, 35, 35, 14, 35 },
- { 21, 21, 35, 35, 35, 35, 21, 21 },
- { 7, 21, 21, 14, 14, 21, 21, 7 },
- { 7, 7, 0, 0, 0, 0, 7, 7 } },
- { /* turm: */
- { 0, 10, 20, 30, 30, 20, 10, 0 },
- { 10, 10, 20, 30, 30, 20, 10, 10 },
- { 20, 20, 20, 25, 25, 20, 20, 20 },
- { 20, 20, 20, 25, 25, 20, 20, 20 },
- { 20, 20, 20, 25, 25, 20, 20, 20 },
- { 20, 20, 20, 25, 25, 20, 20, 20 },
- { 10, 10, 20, 30, 30, 20, 10, 10 },
- { 0, 10, 20, 30, 30, 20, 10, 0 } },
- { /* dame: */
- { 4, 0, 0, 4, 4, 0, 0, 4 },
- { 0, 12, 8, 12, 12, 8, 12, 0 },
- { 0, 8, 20, 20, 20, 20, 8, 0 },
- { 0, 8, 16, 28, 28, 16, 8, 0 },
- { 0, 8, 16, 28, 28, 16, 8, 0 },
- { 0, 8, 20, 20, 20, 20, 8, 0 },
- { 0, 12, 8, 12, 12, 8, 12, 0 },
- { 4, 0, 0, 4, 4, 0, 0, 4 } },
- { /* koenig: */
- { 0, 12, 12, 12, 12, 12, 12, 0 },
- { 12, 30, 30, 30, 30, 30, 30, 12 },
- { 12, 30, 30, 30, 30, 30, 30, 12 },
- { 12, 30, 30, 30, 30, 30, 30, 12 },
- { 12, 30, 30, 30, 30, 30, 30, 12 },
- { 12, 30, 30, 30, 30, 30, 30, 12 },
- { 12, 30, 30, 30, 30, 30, 30, 12 },
- { 0, 12, 12, 12, 12, 12, 12, 0 } } };
-
-
- struct Zugstat * BesterZug( s, fa, ite, sp )
- Figur s[ 9 ][ 9 ];
- Farbe fa;
- int ite;
- Special sp;
- {
- static struct Zugstat zs;
- struct Knoten *k, *ks;
- struct Zug *z;
- long kn;
- int best, ok, sx, sy, zx, zy;
- Figur fi;
- int spz;
-
- Zeit( 0L );
- kn = ZugBaumI( s, &k, &k, fa, ite, sp );
-
- if( kn ) {
- /* besten Zug aussuchen und merken: */
- best = -30000; ks = k;
- do {
- if( ks->zugwertung > best ) {
-
- sx = ks->zug.start >> 4; sy = ks->zug.start & yposmask;
- zx = ks->zug.ziel >> 4; zy = ks->zug.ziel & yposmask;
- /* Zug ausführen: */
- fi = s[zx][zy]; s[sx][sy] = leer; spz = 0;
- if( (ks->zug.figur&figmask)==koenig && (zx-sx==2 ||
- sx-zx==2) ) {
- spz = 1; s[zx][zy] = ks->zug.figur;
- if( zx==7 ) {
- s[6][sy] = s[8][sy]; s[8][sy] = leer;
- } else {
- s[4][sy] = s[1][sy]; s[1][sy] = leer;
- }
- } else if( (ks->zug.figur&figmask)==bauer && fi==leer &&
- sx!=zx ) {
- spz = 1; s[zx][zy] = ks->zug.figur; s[zx][sy] = leer;
- } else if( (ks->zug.figur&figmask)==bauer && (zy==1 ||
- zy==8) ) {
- s[zx][zy] = (ks->zug.figur&farbmask)|dame;
- } else
- s[zx][zy] = ks->zug.figur;
-
- ok = !IstSchach( s, fa, 0, sp );
-
- /* Zug zurücknehmen: */
- s[sx][sy] = ks->zug.figur; s[zx][zy] = fi;
- if( spz )
- if( zx-sx==2 || sx-zx==2 ) {
- if( zx==7 ) {
- s[8][sy] = s[6][sy]; s[6][sy] = leer;
- } else {
- s[1][sy] = s[4][sy]; s[4][sy] = leer;
- }
- } else
- s[zx][sy] = bauer|(zy==6?schwarz:weiss);
-
- ok &= RochOK( s, ks->zug.start, ks->zug.ziel, sp );
-
- if( ok ) { /* ins (bei Roch. durchs) Schach ziehen verboten */
- best = ks->zugwertung;
- z = &(ks->zug);
- } else
- ks->zugwertung = -30000;
- }
- ks = ks->nachbar;
- } while( ks );
- } else
- return( 0L );
-
- zs.zug.figur = z->figur;
- zs.zug.start = z->start;
- zs.zug.ziel = z->ziel;
- LoescheBaum( &k );
- Zeit( &(zs.zeit) );
- zs.knoten = kn;
- zs.wertung = GesamtWert( s, &(zs.zug) );
- return( &zs );
- }
-
- long
- ZugBaumI( s, ks, k, fa, iteration, sp )
- Figur s[ 9 ][ 9 ];
- struct Knoten **ks, **k;
- Farbe fa;
- int iteration;
- Special sp;
- {
- int i, j;
- long knoten;
- Feld *fe;
- Feld fes;
- struct Knoten **kmerk;
- struct Knoten *k1;
-
- knoten = 0;
- kmerk = k;
-
- /* Spielbrett nach eigenen Figuren durchsuchen: */
- for( i=1; i<=8; i++ )
- for( j=1; j<=8; j++ )
- if( (s[ i ][ j ] & farbmask) == fa ) {
-
- /* mögliche Züge der Figur ermitteln: */
- fes = i << 4 | j;
- switch( s[ i ][ j ] & figmask ) {
- case bauer: fe = Bauer( s, fes, sp ); break;
- case springer: fe = Springer( s, fes ); break;
- default: fe = RestFig( s, fes, sp ); break;
- }
-
- /* alle neuen Züge in den Zugbaum: */
- while( *fe ) {
- if(( k1 = GibKnoten()) == 0L ) {
- LoescheBaum( ks );
- SchliesseDisplay();
- exit( 1 );
- }
- knoten ++;
- k1->zug.figur = s[ i ][ j ];
- k1->zug.start = fes;
- k1->zug.ziel = *fe;
- k1->nachbar = k1->nachfolger = 0L;
- *kmerk = k1;
- kmerk = &(k1->nachbar);
- fe ++;
- }
- }
-
- if( knoten )
- /* alle neuen Züge bewerten: */
- knoten += ZugBaumII( s, ks, k, fa, iteration, sp );
-
- return( knoten );
- }
-
- long
- ZugBaumII( s, ks, k, fa, iteration, sp )
- Figur s[ 9 ][ 9 ];
- struct Knoten **ks, **k;
- Farbe fa;
- int iteration;
- Special sp;
- {
- long knoten, kneu;
- int bonus, figwert, best;
- struct Knoten *k1, *k2;
- int sx, sy, zx, zy;
- Figur fi;
- int spz, spbonus;
- Special sps;
-
- knoten = 0;
- k1 = *k;
-
- while( k1 ) {
-
- sx = k1->zug.start >> 4; sy = k1->zug.start & yposmask;
- zx = k1->zug.ziel >> 4; zy = k1->zug.ziel & yposmask;
-
- /* bei Bauernumwandlung gibt's Bonuspunkte: */
- if( (k1->zug.figur & figmask) == bauer && (zy == 1 || zy == 8) )
- bonus = Figurwert[ dame ] - Figurwert[ bauer ];
- else
- bonus = 0;
-
- /* Figuren schlagen bringt auch Punkte: */
- fi = s[ zx ][ zy ];
- figwert = ( fi == leer ) ? 0 : Figurwert[ fi & figmask ] +
- Stellungswert( fi, k1->zug.ziel );
-
- /* jeweils Punkte für Rochade und ep-Schlagen: */
- if( (k1->zug.figur&figmask)==koenig && (zx-sx==2 || sx-zx==2) )
- spbonus = 100;
- else if( (k1->zug.figur&figmask)==bauer && fi==leer && sx!=zx )
- spbonus = 100;
- else
- spbonus = 0;
-
- /* auch Gegenzüge erkunden? */
- if( iteration > 1 ) {
-
- /* neue Special - Variable: */
- sps = sp & ~epmask;
- if( (k1->zug.figur&figmask)==bauer && (zy-sy==2 || sy-zy==2) )
- sps |= sx;
- if( (k1->zug.figur&figmask)==koenig )
- if( (k1->zug.figur&farbmask)==weiss )
- sps &= ~wroch;
- else
- sps &= ~sroch;
- if( (k1->zug.figur&figmask)==turm )
- if( (k1->zug.figur&farbmask)==weiss ) {
- if( sx==1 )
- sps &= ~wlroch;
- else if( sx==8 )
- sps &= ~wkroch;
- } else
- if( sx==1 )
- sps &= ~slroch;
- else
- sps &= ~skroch;
-
- /* Zug auf Spielbrett ausführen: */
- s[sx][sy] = leer; spz = 0;
- if( (k1->zug.figur&figmask)==koenig && (zx-sx==2 || sx-zx==2) ) {
- spz = 1; s[zx][zy] = k1->zug.figur;
- if( zx==7 ) {
- s[6][sy] = s[8][sy]; s[8][sy] = leer;
- } else {
- s[4][sy] = s[1][sy]; s[1][sy] = leer;
- }
- } else if( (k1->zug.figur&figmask)==bauer && fi==leer && sx!=zx ) {
- spz = 1; s[zx][zy] = k1->zug.figur; s[zx][sy] = leer;
- } else if( bonus ) {
- s[zx][zy] = fa|dame;
- } else
- s[zx][zy] = k1->zug.figur;
-
- /* Unterbaum aufbauen lassen: */
- kneu = ZugBaumI( s, ks, &(k1->nachfolger),
- fa == weiss ? schwarz : weiss, iteration-1, sps );
- knoten += kneu;
-
- /* besten Gegenzug ermitteln: */
- if( kneu ) {
- best = -30000;
- k2 = k1->nachfolger;
- do {
- if( k2->zugwertung > best )
- best = k2->zugwertung;
- k2 = k2->nachbar;
- } while( k2 );
- } else
- best = 5000;
-
- /* Unterbaum wegwerfen: */
- LoescheBaum( &(k1->nachfolger) );
-
- /* Zug auf Spielbrett rückgängig machen: */
- s[sx][sy] = k1->zug.figur; s[zx][zy] = fi;
- if( spz )
- if( zx-sx==2 || sx-zx==2 ) {
- if(zx==7) {
- s[8][sy] = s[6][sy]; s[6][sy] = leer;
- } else {
- s[1][sy] = s[4][sy]; s[4][sy] = leer;
- }
- } else
- s[zx][sy] = bauer|(zy==6?schwarz:weiss);
-
- } else
- best = 0;
-
- /* auch Positionswechsel kann Punkte bedeuten: */
- k1->zugwertung = bonus + spbonus + figwert - best +
- Stellungswert( k1->zug.figur, k1->zug.ziel ) -
- Stellungswert( k1->zug.figur, k1->zug.start );
-
- k1 = k1->nachbar;
- }
-
- return( knoten );
- }
-
- LoescheBaum( k )
- struct Knoten **k;
- {
- struct Knoten *k1, *kmerk;
-
- k1 = *k;
- *k = 0L;
- while( k1 ) {
- LoescheBaum( &(k1->nachfolger) );
- kmerk = k1->nachbar;
- NimmKnoten( k1 );
- k1 = kmerk;
- }
- }
-
- Stellungswert( fi, fe )
- Figur fi;
- Feld fe;
- {
- int fstdim;
-
- fstdim = ( fi == wbauer ) ? 0 : ( fi & figmask );
- return( Stelwert[ fstdim ][ 8 - (fe & yposmask) ][ (fe >> 4)-1 ] );
- }
-
- GesamtWert( s, z )
- Figur s[ 9 ][ 9 ];
- struct Zug *z;
- {
- int sx, sy, zx, zy;
- Figur fi;
- int spz;
- long wert;
- int i, j, neu;
- Feld fe;
-
- sx = z->start >> 4; sy = z->start & yposmask;
- zx = z->ziel >> 4; zy = z->ziel & yposmask;
- /* Zug ausführen: */
- fi = s[zx][zy]; s[sx][sy] = leer; spz = 0;
- if( (z->figur&figmask)==koenig && (zx-sx==2 || sx-zx==2) ) {
- spz = 1; s[zx][zy] = z->figur;
- if( zx==7 ) {
- s[6][sy] = s[8][sy]; s[8][sy] = leer;
- } else {
- s[4][sy] = s[1][sy]; s[1][sy] = leer;
- }
- } else if( (z->figur&figmask)==bauer && fi==leer && sx!=zx ) {
- spz = 1; s[zx][zy] = z->figur; s[zx][sy] = leer;
- } else if( (z->figur&figmask)==bauer && (zy==1 || zy==8) ) {
- s[zx][zy] = (z->figur&farbmask)|dame;
- } else
- s[zx][zy] = z->figur;
-
- wert = 0;
- for( i=1; i<=8; i++ )
- for( j=1; j<=8; j++ )
- if( s[ i ][ j ] != leer ) {
- fe = i << 4 | j;
- neu = Figurwert[ s[ i ][ j ] & figmask ] +
- Stellungswert( s[ i ][ j ], fe );
- if( (s[ i ][ j ] & farbmask) == weiss )
- wert += neu;
- else
- wert -= neu;
- }
-
- /* Zug rückgängig machen: */
- s[sx][sy] = z->figur; s[zx][zy] = fi;
- if( spz )
- if( zx-sx==2 || sx-zx==2 ) {
- if( zx==7 ) {
- s[8][sy] = s[6][sy]; s[6][sy] = leer;
- } else {
- s[1][sy] = s[4][sy]; s[4][sy] = leer;
- }
- } else
- s[zx][sy] = bauer|(zy==6?schwarz:weiss);
-
- return( (int)wert );
- }
-